﻿#region GNU GPL Version 3 License

/// Copyright 2013 Shailesh Lolam
/// 
/// This file StorageService.cs is part of AzEzAuto.
/// 
/// AzEzAuto is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
/// 
/// AzEzAuto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
/// 
/// You should have received a copy of the GNU General Public License along with AzEzAuto. If not, see http://www.gnu.org/licenses/.
/// 
/// History:
/// ______________________________________________________________
/// Created         04-2013             Shailesh Lolam

#endregion
      
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XecMe.Core.Tasks;
using AzEzAuto.Entities.Requests;
using AzEzAuto.Entities.Storage;

namespace AzEzAuto.Orchestrate.Tasks
{
    public class StorageService : BaseTask
    {
        protected override void FollowUp(Request req)
        {
            ///IF the request is create storage account then get the storage keys after the creation of the storage account
            if (req.StorageService.Operation == StorageBase.OperationType.Create)
            {
                CreateStorage scr = (CreateStorage)req.StorageService;
                Entities.Storage.StorageService service = _api.Storage.GetStorageKeys(req.SubscriptionId, scr.ServiceName);
                scr.PrimaryKey = service.StorageServiceKeys.Primary;
                scr.SecondaryKey = service.StorageServiceKeys.Secondary;
            }

            ///Remove the surrent request id
            req.CurrentRequestId = null;
        }

        protected override ExecutionState Process(Request req)
        {
            ///If there is no Storage Service part in the request, just move it to next guy in the pipeline
            if (req.StorageService == null)
            {
                WriteToOutputQueue(req);
                return ExecutionState.Executed;
            }

            if (string.IsNullOrEmpty(req.StorageService.ServiceName))
            {
                req.Error = new Error() { RequestId = "-1", Code = "-1", Message = "Service name is missing for the Storage Service request " + req.SubscriptionId };
                WriteToErrorQueue(req);
            }

            switch (req.StorageService.Operation)
            {
                case StorageBase.OperationType.Create:
                    {
                        CreateStorage scr = (CreateStorage)req.StorageService;
                        CreateStorageService r = new CreateStorageService()
                        {
                            ServiceName = scr.ServiceName,
                            Description = scr.Description,
                            Label = scr.Label,
                            Location = scr.Location,
                            GeoReplicationEnabled = scr.GeoReplicationEnabled,
                            AffinityGroup = scr.AffinityGroup
                        };
                        req.CurrentRequestId = _api.Storage.CreateHostedService(req.SubscriptionId, r);
                    }
                    break;
                case StorageBase.OperationType.Update:
                    {
                        UpdateStorage usr = (UpdateStorage)req.StorageService;
                        UpdateStorageService r = new UpdateStorageService()
                        {
                            Description = usr.Description,
                            Label = usr.Label,
                            GeoReplicationEnabled = usr.GeoReplicationEnabled
                        };
                        req.CurrentRequestId = _api.Storage.UpdateStorageService(req.SubscriptionId, r, usr.ServiceName);
                    }
                    break;
                case StorageBase.OperationType.Delete:
                    {
                        DeleteStorage dsr = (DeleteStorage)req.StorageService;
                        req.CurrentRequestId = _api.Storage.DeleteStorageService(req.SubscriptionId, dsr.ServiceName);
                    }
                    break;
                case StorageBase.OperationType.RegenerateKeys:
                    {
                        AzEzAuto.Entities.Requests.RegenerateKeys regen = (AzEzAuto.Entities.Requests.RegenerateKeys)req.StorageService;
                        Entities.Storage.StorageService service = _api.Storage.RegenerateKeys(req.SubscriptionId, regen.ServiceName, new Entities.Storage.RegenerateKeys() { KeyType = Entities.KeyType.Primary });
                        regen.PrimaryKey = service.StorageServiceKeys.Primary;
                        service = _api.Storage.RegenerateKeys(req.SubscriptionId, regen.ServiceName, new Entities.Storage.RegenerateKeys() { KeyType = Entities.KeyType.Secondary });
                        regen.SecondaryKey = service.StorageServiceKeys.Secondary;
                        WriteToOutputQueue(req);
                        return ExecutionState.Executed;
                    }
                default:
                    throw new InvalidOperationException(string.Format("Unknown operation {0} for the Hosted Service for subscription {1}", req.StorageService.Operation, req.SubscriptionId));
            }

            ///Monitor the operation until completed
            RewriteToInputQueue(req);
            return ExecutionState.Executed;
        }

    }
}
